/*-------------------------------------------------------------------------
 *
 * cmdtag.c
 *	  命令标签名称和枚举的数据和例程。
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * IDENTIFICATION
 *	  src/backend/tcop/cmdtag.c
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include "miscadmin.h"
#include "tcop/cmdtag.h"


typedef struct CommandTagBehavior
{
	const char *name;
	const bool	event_trigger_ok;
	const bool	table_rewrite_ok;
	const bool	display_rowcount;
} CommandTagBehavior;

#define PG_CMDTAG(tag, name, evtrgok, rwrok, rowcnt) \
	{ name, evtrgok, rwrok, rowcnt },

static const CommandTagBehavior tag_behavior[COMMAND_TAG_NEXTTAG] = {
#include "tcop/cmdtaglist.h"
};

#undef PG_CMDTAG

void InitializeQueryCompletion(QueryCompletion *fc_qc)
{
	fc_qc->commandTag = CMDTAG_UNKNOWN;
	fc_qc->nprocessed = 0;
}

const char * GetCommandTagName(CommandTag fc_commandTag)
{
	return tag_behavior[fc_commandTag].name;
}

bool command_tag_display_rowcount(CommandTag fc_commandTag)
{
	return tag_behavior[fc_commandTag].display_rowcount;
}

bool command_tag_event_trigger_ok(CommandTag fc_commandTag)
{
	return tag_behavior[fc_commandTag].event_trigger_ok;
}

bool command_tag_table_rewrite_ok(CommandTag fc_commandTag)
{
	return tag_behavior[fc_commandTag].table_rewrite_ok;
}

/*
 * 通过名称搜索 CommandTag
 *
 * 返回 CommandTag，如果无法识别则返回 CMDTAG_UNKNOWN
 */
CommandTag
GetCommandTagEnum(const char *fc_commandname)
{
	const CommandTagBehavior *fc_base,
			   *fc_last,
			   *fc_position;
	int			fc_result;

	if (fc_commandname == NULL || *fc_commandname == '\0')
		return CMDTAG_UNKNOWN;

	fc_base = tag_behavior;
	fc_last = tag_behavior + lengthof(tag_behavior) - 1;
	while (fc_last >= fc_base)
	{
		fc_position = fc_base + ((fc_last - fc_base) >> 1);
		fc_result = pg_strcasecmp(fc_commandname, fc_position->name);
		if (fc_result == 0)
			return (CommandTag) (fc_position - tag_behavior);
		else if (fc_result < 0)
			fc_last = fc_position - 1;
		else
			fc_base = fc_position + 1;
	}
	return CMDTAG_UNKNOWN;
}
